/*
 * FSWUniCEUB - 2008
 * 
 * Este arquivo é de propriedade da Fábrica de Software do UniCEUB
 * 
 * Para mais informações entre em contato com a coordenação do
 * curso de Ciência da Computação da instituição.
 */

package br.uniceub.fsw.indicadores.facade;

import br.uniceub.fsw.arquitetura.persistencia.transacao.Transacao;
import br.uniceub.fsw.arquitetura.servico.exception.NegocioException;
import br.uniceub.fsw.indicadores.bo.ValorDadoPrimarioBO;
import br.uniceub.fsw.indicadores.bo.ValorIndicadorBO;
import br.uniceub.fsw.indicadores.dao.IndicadorDAO;
import br.uniceub.fsw.indicadores.vo.IndicadorVO;
import br.uniceub.fsw.indicadores.dao.ValorIndicadorDAO;
import br.uniceub.fsw.indicadores.vo.ValorIndicadorVO;
import br.uniceub.fsw.indicadores.dao.DadoPrimarioDAO;
import br.uniceub.fsw.indicadores.vo.DadoPrimarioVO;
import br.uniceub.fsw.indicadores.dao.ValorDadoPrimarioDAO;
import br.uniceub.fsw.indicadores.vo.ValorDadoPrimarioVO;
import java.util.ArrayList;
import java.util.List;
import java.text.SimpleDateFormat;
import java.text.ParseException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Facade da entidade Indicador.
 * 
 * @author Marcos Mello Nobrega Soares ra2013617/8
 */
public class ValorIndicadorFacade {
    /**
     * Mensagem de retorno do sistema.
     */
    private String message;
    
    /**
     * Value object do valor indicador.
     */
    private ValorIndicadorVO valorIndicador;

    /**
     * Value object do indicador.
     */
    private IndicadorVO indicador;
    
    /**
     * Lista de indicadores ativos
     */
    private List<List> indicadores;    
       
    /**
     * Lista de dados primários para o indicador selecionado
     */
    private List<DadoPrimarioVO> dadosPrimarios;
    
    /**
     * Lista de valores de dados primários para o indicador selecionado
     */
    private List<ValorDadoPrimarioVO> valoresDadosPrimarios;
    
    /**
     * Construtor da classe.
     */
    public ValorIndicadorFacade() {  
        this.indicadores = new ArrayList<List>();
        
        // indicadores ativos
        IndicadorVO indExemplo = new IndicadorVO();
        indExemplo.setStIndicadorAtivo("S");
        List<IndicadorVO> inds = new IndicadorDAO().consultarPorExemplo(indExemplo);
        
        for(int i = 0; i < inds.size(); i++) {
            List<String> temp = new ArrayList<String>();
            temp.add(inds.get(i).getIdIndicador().toString());
            temp.add(inds.get(i).getNoIndicador().toString());
            temp.add(inds.get(i).getDsIndicador().toString());
            temp.add(inds.get(i).getPeriodicidade().getDsPeriodicidade().toString());            
            temp.add(inds.get(i).getDimensao().getNoDimensao().toString());            
            temp.add(inds.get(i).getStIndicadorManual().toString());            
            this.indicadores.add(temp);
        }
    }
    
    /**
     * Getter da mensagem de retorno.
     * 
     * @return Mensagem de retorno.
     */
    public String getMessage() {
        String retorno = null;
        if(this.message == null || this.message.isEmpty()) {
            retorno = "&nbsp";
        } else {
            retorno = this.message;
        }
        return retorno;
    }
    
    /**
     * Retorna o indicador.
     * 
     * @return Objeto indicador.
     */
    public ValorIndicadorVO getValorIndicador() {
        return this.valorIndicador;
    }
    
    /**
     * Retorna o indicador.
     * 
     * @return Objeto indicador.
     */
    public IndicadorVO getIndicador() {
        return this.indicador;
    }
    
    /**
     * Retorna os Indicadores ativos.
     * 
     * @return Lista de Indicadores ativos.
     */
    public List<List> getIndicadores() {
        return this.indicadores;
    }
    
    /**
     * Retorna os dados primários para o indicador.
     * 
     * @return Lista de dados primários.
     */
    public List<DadoPrimarioVO> getDadosPrimarios() {
        return this.dadosPrimarios;
    }
    
    /**
     * Retorna os valores de dados primários para o indicador.
     * 
     * @return Lista de valores dados primários.
     */
    public List<ValorDadoPrimarioVO> getValoresDadosPrimarios() {
        return this.valoresDadosPrimarios;
    }
     
    /**
     * Responsável por executar a operação selecionada pelo usuário.
     * 
     * @param req Requisição web do tipo HTTP.
     * @param resp Resposta da requisição HTTP.
     */
    public void operacao(HttpServletRequest req, HttpServletResponse resp) {
        String oper = req.getParameter("operacao");

        if(req.getParameter("idIndicador") != null && req.getParameter("idIndicador").length() > 0) {
            try {
                indicador = new IndicadorDAO().consultarPorId(Integer.parseInt(req.getParameter("idIndicador")));
                if(indicador != null)
                    dadosPrimarios = new DadoPrimarioDAO().consultarPorIndicador(indicador);
            }
            catch (NumberFormatException e) {             
            }
        }
        if(oper != null)
        {
            if (oper.equals("registrar")) {
                this.registrar(req, resp);
            } 
             if (oper.equals("calcular")) {
                this.calcular(req, resp);
            } 
        }        
    }

    
    /**
     * Calcular um valor de indicador.
     * 
     * @param req Requisição web do tipo HTTP.
     * @param resp Resposta da requisição HTTP.
     */
    public void calcular(HttpServletRequest req, HttpServletResponse resp) {
        
        if(indicador != null) {
            
            try {
                valorIndicador = new ValorIndicadorBO().calculaIndicador(indicador.getIdIndicador(), true);
            }
            catch(NegocioException e) {
                this.message = e.getMessage();
            }
            catch(Exception e) {
                this.message = e.getMessage();
            }
        }
        else
            this.message = "Indicador não informado.";
    }
    
    /**
     * Registrar um valor de indicador.
     * 
     * @param req Requisição web do tipo HTTP.
     * @param resp Resposta da requisição HTTP.
     */
    public void registrar(HttpServletRequest req, HttpServletResponse resp) {
        String mensagem = "";
        SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
        int i;

        valorIndicador = new ValorIndicadorVO();

        try {
            valorIndicador.setCdIndicador(Integer.parseInt(req.getParameter("idIndicador")));
            indicador = new IndicadorDAO().consultarPorId(valorIndicador.getCdIndicador());
        }
        catch (NumberFormatException e) {             
        }
        
        try {
            if(!req.getParameter("vlValorIndicador").trim().isEmpty())
                valorIndicador.setVlValorIndicador(Float.parseFloat(req.getParameter("vlValorIndicador")));
        }
        catch (NumberFormatException e) {   
            mensagem = mensagem + "Valor do cálculo não é um número.<br />";
        }

        try {
            if(!req.getParameter("dtValorIndicador").trim().isEmpty()) 
                valorIndicador.setDtValorIndicador(sdf.parse(req.getParameter("dtValorIndicador").trim()));
        }        
        catch (ParseException e) {  
            mensagem = mensagem + "Data de cálculo não é uma data existente.<br />";
        }
        
        if(indicador != null) {
            
            String parameter = "";
            float valor;
            DadoPrimarioVO exemploDadoPrimario = new DadoPrimarioVO();
            exemploDadoPrimario.setCdIndicador(indicador.getIdIndicador());
            ValorDadoPrimarioVO valorDadoPrimario;            
            valoresDadosPrimarios = new ArrayList<ValorDadoPrimarioVO>();
            ValorDadoPrimarioBO valorDadoPrimarioBO = new ValorDadoPrimarioBO();

            for(i = 0; i < dadosPrimarios.size(); i++) {                 
                parameter = "dadoPrimario_" + dadosPrimarios.get(i).getIdDadoPrimario();
                try {
                    if(req.getParameter(parameter) != null && req.getParameter(parameter).trim().length() > 0) {
                        valor = Float.parseFloat(req.getParameter(parameter).trim());
                        valorDadoPrimario = new ValorDadoPrimarioVO();
                        valorDadoPrimario.setCdDadoPrimario(dadosPrimarios.get(i).getIdDadoPrimario());                        
                        valorDadoPrimario.setVlValorDadoPrimario(valor);
                        valoresDadosPrimarios.add(valorDadoPrimario);
                        try {
                            valorDadoPrimario.setCdValorIndicador(0);
                            valorDadoPrimarioBO.validaValorDadoPrimario(valorDadoPrimario);
                        }
                        catch (NegocioException e) {
                            mensagem = mensagem + e.getMessage().replace("\n","<br />");
                        }
                        catch (Exception e) {
                           mensagem = mensagem + "Erro desconhecido: " + e.getMessage() + "<br />";
                        } 
                    }
                    else
                        mensagem = mensagem + "Dado primário \"" + dadosPrimarios.get(i).getNoDadoPrimario() + "\" obrigatório.<br/>";
                }
                catch(NumberFormatException e) {
                    mensagem = mensagem + "Dado primário \"" + dadosPrimarios.get(i).getNoDadoPrimario() + "\" não é um número.<br/>";
                }
            }
            
            try {
                new ValorIndicadorBO().validaValorIndicador(valorIndicador);
            }
            catch(NegocioException e) {
                mensagem = mensagem + e.getMessage().replace("\n","<br />");
            }
            catch(Exception e) {
                mensagem = mensagem + e.getMessage() + "<br/>";
            }
            
            if(mensagem.equals("")) {                 
            
                try {
                    ValorDadoPrimarioDAO valorDadoPrimarioDAO = new ValorDadoPrimarioDAO();
                    
                    Transacao.iniciar();
                
                    new ValorIndicadorDAO().inserir(valorIndicador);
                    
                    for(i = 0; i < valoresDadosPrimarios.size(); i++) {
                        valoresDadosPrimarios.get(i).setCdValorIndicador(valorIndicador.getIdValorIndicador());
                        valorDadoPrimarioDAO.inserir(valoresDadosPrimarios.get(i));
                    }
              
                    Transacao.efetivar();
                
                    mensagem = "Registro de valor de indicador realizado com sucesso.";   
                    valorIndicador = null;
                    valoresDadosPrimarios = null;
                } catch (Exception ex) {
                    Transacao.desfazer();
                    mensagem = "Problema no registro do valor do indicador: " + ex.getMessage();
                }
            }
        }
        
        this.message = mensagem;
    }
}